package cn.iocoder.an.module.business.service.repairrequest;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.an.framework.common.enums.UserTypeEnum;
import cn.iocoder.an.framework.common.util.business.CreateRepairNo;
import cn.iocoder.an.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.an.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.an.module.business.controller.admin.repairtask.vo.RepairTaskSaveReqVO;
import cn.iocoder.an.module.business.dal.dataobject.equipmentmanage.EquipmentManageDO;
import cn.iocoder.an.module.business.dal.dataobject.repairtask.RepairTaskDO;
import cn.iocoder.an.module.business.dal.mysql.repairtask.RepairTaskMapper;
import cn.iocoder.an.module.business.service.equipmentmanage.EquipmentManageService;
import cn.iocoder.an.module.business.service.repairtask.RepairTaskService;
import cn.iocoder.an.module.business.utils.WeComMessageUtil;
import cn.iocoder.an.module.system.api.notify.NotifyMessageSendApi;
import cn.iocoder.an.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
import cn.iocoder.an.module.system.dal.dataobject.dict.DictDataDO;
import cn.iocoder.an.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.an.module.system.service.dict.DictDataService;
import cn.iocoder.an.module.system.service.permission.PermissionService;
import cn.iocoder.an.module.system.service.user.AdminUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import cn.iocoder.an.module.business.controller.admin.repairrequest.vo.*;
import cn.iocoder.an.module.business.dal.dataobject.repairrequest.RepairRequestDO;
import cn.iocoder.an.framework.common.pojo.PageResult;
import cn.iocoder.an.framework.common.pojo.PageParam;
import cn.iocoder.an.framework.common.util.object.BeanUtils;

import cn.iocoder.an.module.business.dal.mysql.repairrequest.RepairRequestMapper;

import static cn.iocoder.an.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.an.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.an.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.an.module.business.enums.ErrorCodeConstants.*;

/**
 * 维修申请 Service 实现类
 *
 * @author zzy
 */
@Service
@Validated
public class RepairRequestServiceImpl implements RepairRequestService {

    @Resource
    private RepairRequestMapper repairRequestMapper;

    @Resource
    private EquipmentManageService equipmentService;

    @Resource
    private AdminUserService userService;

    @Resource
    private RepairTaskMapper taskMapper;

    @Resource
    private PermissionService permissionService;

    @Autowired
    private WeComMessageUtil weComMessageUtil;

    @Resource
    private NotifyMessageSendApi notifySendApi;


    @Resource
    private DictDataService dictDataService;


    @Override
    public Long createRepairRequest(RepairRequestSaveReqVO createReqVO) {
        //生成唯一编号
        String prefix = CreateRepairNo.PREFIX;
        String yearMonth = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
        String repairNo = CreateRepairNo.generateNextCode(repairRequestMapper.findMaxRepairtNo(prefix + yearMonth));
        createReqVO.setRepairNo(repairNo);

        //设置其他信息
        setOtherData(createReqVO);

        RepairRequestDO repairRequest = BeanUtils.toBean(createReqVO, RepairRequestDO.class);
        repairRequestMapper.insert(repairRequest);

        //企业微信消息推送
        sendRepairMessage(repairRequest.getDutyUserId());
        // 返回
        return repairRequest.getId();
    }

    @Override
    public void updateRepairRequest(RepairRequestSaveReqVO updateReqVO) {
        // 校验存在
        validateRepairRequestExists(updateReqVO.getId());
        //设置其他信息
        setOtherData(updateReqVO);
        // 更新
        RepairRequestDO updateObj = BeanUtils.toBean(updateReqVO, RepairRequestDO.class);
        repairRequestMapper.updateById(updateObj);
    }

    @Override
    public void deleteRepairRequest(Long id) {
        // 校验存在
        validateRepairRequestExists(id);
        // 删除
        repairRequestMapper.deleteById(id);
    }

    @Override
    public void deleteRepairRequestListByIds(List<Long> ids) {
        // 删除
        repairRequestMapper.deleteByIds(ids);
    }


    private void validateRepairRequestExists(Long id) {
        if (repairRequestMapper.selectById(id) == null) {
            throw exception(REPAIR_REQUEST_NOT_EXISTS);
        }
    }

    @Override
    public RepairRequestDO getRepairRequest(Long id) {
        return repairRequestMapper.selectById(id);
    }

    @Override
    public PageResult<RepairRequestDO> getRepairRequestPage(RepairRequestPageReqVO pageReqVO) {
        return repairRequestMapper.selectPage(pageReqVO);
    }

    @Override
    public PageResult<RepairRequestDO> getRepairRequestTaskPage(RepairRequestPageReqVO pageReqVO) {
        //参与的维修申请单或任务单

        //1.查询出当前登录人是维修人的或者是申请人创建人所有的申请单ID
        Long currentUserId = SecurityFrameworkUtils.getLoginUserId();

        if (permissionService.hasAnyRoles(SecurityFrameworkUtils.getLoginUserId(),"super_admin","tenant_admin")) {//判断是不是管理员

            // 是管理员 看全部信息
        } else {

            List<Object> requestIdObjects = repairRequestMapper.selectObjs(
                    new QueryWrapper<RepairRequestDO>()
                            .select("id")
                            .apply("JSON_CONTAINS(duty_user_id, CAST({0} AS JSON))", "[" + currentUserId + "]")
                            .or()
                            .eq("request_user_id", currentUserId)
                            .or()
                            .eq("creator", currentUserId)
            );

            // 转换为 List<Long>
            List<Long> requestIds = requestIdObjects.stream()
                    .map(obj -> (Long) obj)
                    .collect(Collectors.toList());


            Set<Long> uniqueIds = new HashSet<>();
            uniqueIds.addAll(requestIds);

            // 如果需要返回 List
            List<Long> combinedIds = new ArrayList<>(uniqueIds);
            pageReqVO.setIds(combinedIds);
            if (CollectionUtils.isEmpty(combinedIds)) {
                return PageResult.empty(); // 提前返回空列表，避免执行 SQL;
            }
        }
        return repairRequestMapper.selectTaskPage(pageReqVO);
    }


    public void setOtherData(RepairRequestSaveReqVO saveReqVO) {
        //生成维修编号

        //新增修改默认设置状态为待接收
        saveReqVO.setStatus(1);

        //新增修改默认设置是否解决为未解决
        saveReqVO.setResolved(1);

        //设置设备名称
        Long equipmentId = saveReqVO.getEquipmentId();
        EquipmentManageDO equipmentManage = equipmentService.getEquipmentManage(equipmentId);
        saveReqVO.setEquipmentName(equipmentManage.getEquipmentName());

        //设置申请人名称
        Long requestUserId = saveReqVO.getRequestUserId();
        AdminUserDO user = userService.getUser(requestUserId);
        saveReqVO.setRequestUserName(user.getNickname());

        //设置维修人并推送消息
        List<Long> dutyUserId = saveReqVO.getDutyUserId();
        List<AdminUserDO> userList = userService.getUserList(dutyUserId);
        String dutyUserName = userList.stream()
                .map(AdminUserDO::getNickname)                    // 提取 nickname
                .filter(nickname -> nickname != null && !nickname.trim().isEmpty()) // 过滤 null/空
                .collect(Collectors.joining(","));               // 用逗号拼接
        saveReqVO.setDutyUserName(dutyUserName);

    }

    //推送企业微信消息 系统内消息推送
    public void sendRepairMessage(List<Long> dutyUserId) {
        //推送消息
        List<AdminUserDO> userList = userService.getUserList(dutyUserId);
        String userIds = "";
        StringBuilder userIdBuilder = new StringBuilder();

        // 获取当前时间并格式化
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedNow = now.format(formatter);

        for (AdminUserDO user : userList) {
            // 1. 推送系统消息 准备参数
            String templateCode = "wx-6"; // 站内信模版，记得在【站内信管理】中配置噢
            Map<String, Object> templateParams = new HashMap<>();
            templateParams.put("time", formattedNow);
            NotifySendSingleToUserReqDTO sendToUserDTO = new NotifySendSingleToUserReqDTO();
            sendToUserDTO.setUserId(user.getId());
            sendToUserDTO.setTemplateCode(templateCode);
            sendToUserDTO.setTemplateParams(templateParams);
            Long l = notifySendApi.sendSingleMessageToAdmin(sendToUserDTO);
            System.out.printf("系统内消息通知:", l);

            String userId = weComMessageUtil.getUserIdByMobile(user.getEnterpriseWeChatAccount());
            if (userId != null && !userId.trim().isEmpty()) {
                // 如果已经有内容了，先添加分隔符
                if (userIdBuilder.length() > 0) {
                    userIdBuilder.append("|");
                }
                userIdBuilder.append(userId);
            }
        }

        // 将 StringBuilder 转换为最终的字符串
        userIds = userIdBuilder.toString();
        // 可选：检查最终结果是否为空
        if (userIds.isEmpty()) {
            // 处理没有找到任何有效用户ID的情况
            System.out.printf("没有找到任何有效的企业微信 UserID");
            return;
        }

        // 1. 使用 sendTextMessage 方法 (更灵活，可以同时指定用户、部门、标签)

        //从字典配置中获取发送的消息
        DictDataDO wxMessage = dictDataService.getDictData("wx_message", "1");
        String systemMessage = wxMessage.getLabel() + formattedNow;
        // 将时间戳添加到消息中
        WeComMessageUtil.WeComSendResult weComSendResult = weComMessageUtil.sendTextMessage(systemMessage, userIds, null, null);
        System.out.printf("推送结果:" + weComSendResult.toString());

    }


}